package com.hehe.boot.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hehe.boot.mapper.ReservationMapper;
import com.hehe.boot.pojo.Doctor;
import com.hehe.boot.pojo.Reservation;
import com.hehe.boot.pojo.ReservationHttp.ReservationAddRequest;
import com.hehe.boot.pojo.ReservationHttp.ReservationDoctorListResponse;
import com.hehe.boot.pojo.ReservationHttp.ReservationUserListResponse;
import com.hehe.boot.pojo.User;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class ReservationService extends ServiceImpl<ReservationMapper, Reservation> {

    private final DoctorService doctorService;
    private final UserService userService;

    public ReservationService(DoctorService doctorService,UserService userService) {
        this.doctorService = doctorService;
        this.userService = userService;
    }

    @Transactional
    public Long addReservation(ReservationAddRequest request) {
        Reservation reservation = new Reservation();
        reservation.setUserId(request.getUserId());
        reservation.setDoctorId(request.getDoctorId());

        QueryWrapper<Doctor> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", request.getDoctorId());
        Doctor existingDoctor = doctorService.getOne(queryWrapper);

        if (existingDoctor == null){
            return new Long(-1);
        }

        LocalDateTime start = existingDoctor.getWorkStart();
        LocalDateTime end = existingDoctor.getWorkEnd();
        Integer times = existingDoctor.getWorkTimes();
        Integer remain = existingDoctor.getRemain();

        if (remain<=0){
            return new Long(-1);
        }

        // 计算总时间跨度
        Duration totalDuration = Duration.between(start, end);

        // 计算每段的时间跨度
        long secondsPerSegment = totalDuration.getSeconds() / times;

        // 计算第n段的开始时间
        LocalDateTime segmentStart = existingDoctor.getWorkStart().plusSeconds(secondsPerSegment*(times-remain));

        reservation.setReserveTime(segmentStart);

        //数据库减少Doctor的remain的次数
        UpdateWrapper<Doctor> updateWrapper = new UpdateWrapper();
        updateWrapper.eq("id",request.getDoctorId());
        updateWrapper.set("remain",remain-1);
        this.doctorService.update(updateWrapper);

        Boolean flag = this.save(reservation);
        if (flag == true){
            new Long(-2);
        }

        return reservation.getId();
    }

    @Transactional
    public List<ReservationUserListResponse> userList(Long userId) {

        QueryWrapper<Reservation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);

        List<Reservation> result = this.list(queryWrapper);

        List<ReservationUserListResponse> list = new ArrayList<>();

        for (Reservation iterm : result){
            ReservationUserListResponse response = new ReservationUserListResponse();

            Doctor doctor = doctorService.getById(iterm.getDoctorId());

            response.setReservationId(iterm.getId());
            response.setDoctorId(doctor.getId());
            response.setReserveTime(iterm.getReserveTime());
            response.setDoctorName(doctor.getName());
            response.setDoctorWorkRoom(doctor.getWorkRoom());

            list.add(response);
        }

        return list;
    }

    @Transactional
    public List<ReservationDoctorListResponse> doctorList(Long doctorId) {
        QueryWrapper<Reservation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("doctor_id", doctorId);

        List<Reservation> result = this.list(queryWrapper);

        List<ReservationDoctorListResponse> list = new ArrayList<>();

        for (Reservation iterm : result){
            ReservationDoctorListResponse response = new ReservationDoctorListResponse();

            User user = userService.getById(iterm.getUserId());

            response.setReservationId(iterm.getId());
            response.setReserveTime(iterm.getReserveTime());
            response.setUserName(user.getName());

            list.add(response);
        }

        return list;
    }


}
